import React, { Component } from 'react'

// 声明周期表http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

export default class UserItemClass extends Component {

    constructor(props){
        console.log("挂载-生命周期1 UserItemClass.js 的 constructor （初始化对象，调用super()）")
        super(props);
        // 静态更新状态的值
        this.state = {
            enableText: ''
        }
    }

    // 做静态更新(静态的生命周期没有this，return 一个对象，他会自动放到this对象的属性下)
    static getDerivedStateFromProps(props){
        //会在调用 render 方法之前调用，并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state，如果返回 null 则不更新任何内容。
        console.log("挂载2/更新1-生命周期 UserItemClass.js 的 getDerivedStateFromProps 从Props获取数据到State里面")
        return {
            enableText: props.completed ? "开启" : '未开启'
        }
    }

    shouldComponentUpdate(nextProps, nextState){
        //console.log("更新2-生命周期 UserItemClass.js 的 shouldComponentUpdate 询问是否许哟更新。返回真表示更新，否则就不会执行下面的声明周期")
        //console.log(nextProps, nextState)
        //console.log(this.props, this.state)
        // return true
        // 如果不是深度比较两个对象是否改变，直接把Component组件换成PureComponent（浅比较）也能解决，深度比较需要lodash 的isEques做深度比较，性能影响大，有hash算法比较的
        return nextProps.completed !== this.props.completed
    }

    threeFunctionExec = () => {
        console.log("我是第三层的组件，准备调用父组件的函数")
        // 增加是否为空的判断
        //this.props.threeEditUserEnableFn && this.props.threeEditUserEnableFn(this.props.id) // 返回勾选change的id
        // 或者使用空函数
        const {
            // threeEditUserEnableFn = () => {},
            threeEditUserEnableFn = noop,
            id
        } = this.props
        threeEditUserEnableFn(id)
    }

    // 如果 shouldComponentUpdate() 返回 false，则不会调用 render()。
    render() {
        console.log("挂载3/更新3-生命周期 UserItemClass.js 的 render （渲染dom，合成虚拟dom）")
        // 简化下面取值省略this.props.
        const {
            completed,
            title
        } = this.props // 把props对象值赋值到对象对应字段

        return (
            //  <li key={this.props.id}>
            <li>
                <input type="checkbox" checked={completed}
                    onChange={this.threeFunctionExec}
                />
                <span>{title} 
                {completed ? "开启" : '未开启'}
                {/* {this.state.enableText} */}
                </span>
            </li>
        )
    }

    // 该生命周期可以获取真实dom和虚拟合成dom等对象信息
    componentDidMount(){
        // componentDidMount() 会在组件挂载后（插入 DOM 树中）立即调用。依赖于 DOM 节点的初始化应该放在这里。如需通过网络请求获取数据，此处是实例化请求的好地方。
        console.log("挂载-生命周期4 UserItemClass.js 的 componentDidMount （合成虚拟dom，挂载完成，可以发ajax请求等）")
        //console.log(this.props , this.state)
        console.log( this.state)
    }
    // getSnapshotBeforeUpdate(prevProps, prevState){
    //     // componentDidUpdate() 会在更新后会被立即调用。首次渲染不会执行此方法。
    //     console.log("更新4-生命周期4 UserItemClass.js 的 getSnapshotBeforeUpdate （在最近一次渲染输出（提交到 DOM 节点）之前调用）")
    // }

    componentDidUpdate(prevProps, prevState, snapshot) {
        // 如果我们 snapshot 有值，说明我们刚刚添加了新的 items，
        // 调整滚动位置使得这些新 items 不会将旧的 items 推出视图。
        //（这里的 snapshot 是 getSnapshotBeforeUpdate 的返回值）
        // if (snapshot !== null) {
        //   const list = this.listRef.current;
        //   list.scrollTop = list.scrollHeight - snapshot;
        // }
        console.log("更新5-生命周期4 UserItemClass.js 的 componentDidUpdate （会在更新后会被立即调用。首次渲染不会执行此方法")
      }
}

